package pe.com.bbva.ge.negocio.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pe.com.bbva.ge.domain.base.BaseDomain;
import pe.com.bbva.ge.domain.base.Identificador;
import pe.com.bbva.ge.domain.configuracion.Denominacion;
import pe.com.bbva.ge.domain.configuracion.Posicion;
import pe.com.bbva.ge.domain.configuracion.Regla;
import pe.com.bbva.ge.domain.configuracion.Valor;
import pe.com.bbva.ge.domain.solicitud.Destino;
import pe.com.bbva.ge.domain.solicitud.DetalleCasetera;
import pe.com.bbva.ge.domain.solicitud.DetalleDenominacion;
import pe.com.bbva.ge.domain.solicitud.DetalleMaterial;
import pe.com.bbva.ge.domain.solicitud.DetalleMoneda;
import pe.com.bbva.ge.domain.solicitud.DetalleOtroServicio;
import pe.com.bbva.ge.domain.solicitud.EstadoSolicitud;
import pe.com.bbva.ge.domain.solicitud.Remito;
import pe.com.bbva.ge.domain.solicitud.Solicitud;
import pe.com.bbva.ge.domain.solicitud.TipoSolicitud;
import pe.com.bbva.ge.negocio.ConfiguracionNegocio;
import pe.com.bbva.ge.negocio.SolicitudNegocio;
import pe.com.bbva.ge.persistencia.orm.SolicitudORM;
import pe.com.bbva.ge.utileria.UtileriaComun;
import pe.com.bbva.ge.utileria.drools.MotorDrools;
import pe.com.bbva.ge.utileria.form.BandejaTrabajoForm;

@Service
public class SolicitudNegocioImpl extends CrudNegocioImpl implements
		SolicitudNegocio {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6749120561956090992L;

	@Autowired
	private ConfiguracionNegocio genericoNegocio;

	@Autowired
	private MotorDrools motorDrools;

	@Autowired
	private SolicitudORM gestionarSolicitudORM;
	
	public List<Solicitud> obtenerSolicitudesPendientes(BandejaTrabajoForm bandejaTrabajoForm)
	{
		List<Solicitud> list1 = gestionarSolicitudORM.obtenerSolicitudesPendientes1(bandejaTrabajoForm);
		List<Solicitud> list2 = gestionarSolicitudORM.obtenerSolicitudesPendientes2(bandejaTrabajoForm);
		List<Solicitud> list3 = gestionarSolicitudORM.obtenerSolicitudesPendientes3(bandejaTrabajoForm);
		
		List<Solicitud> list12 = ListUtils.union(list1, list2);
		
		return ListUtils.union(list12, list3);
	}

	public List<Destino> obtenerDestinos(Solicitud solicitud) {
		return gestionarSolicitudORM.obtenerDestinos(solicitud);
	}

	public List<DetalleMoneda> obtenerDetalleMonedas(Destino destino) {
		return gestionarSolicitudORM.obtenerDetalleMonedas(destino);
	}

	public List<DetalleDenominacion> obtenerDetalleDenominaciones(
			DetalleMoneda detalleMoneda) {
		return gestionarSolicitudORM
				.obtenerDetalleDenominaciones(detalleMoneda);
	}

	@Override
	public List<DetalleCasetera> obtenerDetalleCasetera(Destino destino) {
		return gestionarSolicitudORM.obtenerDetalleCasetera(destino);
	}

	@Override
	public DetalleMoneda obtenerDetalleMonedaXIdMoneda(Destino destino,
			Valor moneda) {
		return gestionarSolicitudORM.obtenerDetalleMonedaXIdMoneda(destino,
				moneda);
	}

	@Override
	public List<Remito> obtenerRemitos(DetalleMoneda detalleMoneda) {
		return gestionarSolicitudORM.obtenerRemitos(detalleMoneda);
	}

	@Override
	public DetalleMoneda obtenerDetalleMoneda(Destino destino, Valor moneda) {
		return gestionarSolicitudORM.obtenerDetalleMoneda(destino, moneda);
	}

	@Override
	@Transactional
	public void crearSolicitud(Solicitud solicitud) {

		String prefijo = UtileriaComun.convertirFechaString(
				solicitud.getAtencion(), "yyyyMMddHHmm");
		long contador = contar(Solicitud.class) + 1;
		String numero = StringUtils.leftPad(String.valueOf(contador), 6, "0");
		solicitud.setNumero(prefijo + numero);
		asignarEstado(solicitud);
		/*
		 * List<Destino> destinos = solicitud.getDestinos(); for (Destino
		 * destino : destinos) { List<DetalleMoneda> detalleMonedas =
		 * destino.getDetalleMonedas(); destino.setSolicitud(solicitud); for
		 * (DetalleMoneda detalleMoneda : detalleMonedas) {
		 * detalleMoneda.setDestino(destino);
		 * 
		 * List<DetalleDenominacion> detalleDenominacions =
		 * detalleMoneda.getDetalleDenominaciones(); for (DetalleDenominacion
		 * detalleDenominacion : detalleDenominacions) {
		 * detalleDenominacion.setDetalleMoneda(detalleMoneda); } } }
		 */
		crear(solicitud);
		/*
		 * grabarTodos(solicitud.getDestinos()); for (Destino destino :
		 * destinos) { List<DetalleMoneda> detalleMonedas =
		 * destino.getDetalleMonedas(); grabarTodos(detalleMonedas); for
		 * (DetalleMoneda detalleMoneda : detalleMonedas) {
		 * List<DetalleDenominacion> detalleDenominacions =
		 * detalleMoneda.getDetalleDenominaciones();
		 * grabarTodos(detalleDenominacions); } }
		 */
	}

	@Override
	@Transactional
	public void actualizarSolicitud(Solicitud solicitud) {
		asignarEstado(solicitud);
		modificar(solicitud);
	}

	@Transactional
	private void asignarEstado(Solicitud solicitud) {
		List<Regla> reglas = genericoNegocio.obtenerTodos(Regla.class);
		List<BaseDomain> objetos = new ArrayList<BaseDomain>();
		objetos.add(solicitud);
		motorDrools.ejecutarReglas(objetos, reglas);
		EstadoSolicitud estadoSolicitud = genericoNegocio.obtenerEntidadPorCodigo(solicitud.getEstado(),EstadoSolicitud.class);
		solicitud.setEstado(estadoSolicitud);
	}

	@Override
	public List<DetalleMaterial> obtenerDetalleMateriales(Destino destino) {
		return gestionarSolicitudORM.obtenerDetalleMateriales(destino);
	}

	@Override
	public List<DetalleOtroServicio> obtenerDetalleOtroServicios(Destino destino) {
		return gestionarSolicitudORM.obtenerDetalleOtroServicios(destino);
	}

	@Override
	public boolean primerPedido(TipoSolicitud tipoSolicitud,Posicion posicionDestino) {
		List<Destino> lstDestino=gestionarSolicitudORM.obtenerPrimerPedido(tipoSolicitud,posicionDestino);
		return lstDestino.size()>0;
	}

}
